package jsr166.contrib.uncontended;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.locks.ReadWriteLock;


 class ReadWriteLockedCollection<E, C extends Collection<E> > implements Collection<E> {
    
    final ReadWriteLock rwLock;
    final C base;
    ReadWriteLockedCollection(C base, ReadWriteLock rwLock) {
        this.base = base;
        this.rwLock = rwLock;
    }
    
     public boolean add(E arg0) {
        rwLock.writeLock().lock();
        try {
            return base.add(arg0);
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public boolean addAll(Collection<? extends E> arg0) {
        rwLock.writeLock().lock();
        try {
            return base.addAll(arg0);
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public void clear() {
        rwLock.writeLock().lock();
        try {
             base.clear();
        } finally {
            rwLock.writeLock().unlock();
        }
        
    }

    public boolean contains(Object arg0) {
        rwLock.readLock().lock();
        try {
             return base.contains(arg0);
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public boolean containsAll(Collection<?> arg0) {
        rwLock.readLock().lock();
        try {
             return base.containsAll(arg0);
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public boolean isEmpty() {
        rwLock.readLock().lock();
        try {
             return base.isEmpty();
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public Iterator<E> iterator() {
        rwLock.readLock().lock();
        try {
             return new ReadWriteLockedIterator<E, Iterator<E>>(base.iterator(), rwLock);
        } finally {
            rwLock.readLock().unlock();
        }
    }
    
    public boolean remove(Object arg0) {
        rwLock.writeLock().lock();
        try {
             return base.remove(arg0);
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public boolean removeAll(Collection<?> arg0) {
        rwLock.writeLock().lock();
        try {
             return base.removeAll(arg0);
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public boolean retainAll(Collection<?> arg0) {
        rwLock.writeLock().lock();
        try {
             return base.retainAll(arg0);
        } finally {
            rwLock.writeLock().unlock();
        }
    }

    public int size() {
        rwLock.readLock().lock();
        try {
             return base.size();
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public Object[] toArray() {
        rwLock.readLock().lock();
        try {
             return base.toArray();
        } finally {
            rwLock.readLock().unlock();
        }
    }

    public <T> T[] toArray(T[] arg0) {
        rwLock.readLock().lock();
        try {
             return base.toArray(arg0);
        } finally {
            rwLock.readLock().unlock();
        }
    }

}
